package security.SingleAccessPoint;

import security.Checkpoint.Checkpoint;

public abstract aspect SingleAccessPointAspect {
	
	protected Checkpoint checkpoint =  Checkpoint.getCheckpoint();
	protected String session_id = null;
	
	/**
	 * TODO: remove
	 * This is the code within our own security package
	 */
	public pointcut securityPackage(): within(security.*) ; 
	
	/**
	 * TODO: remove
	 * This is all the public code
	 */
	public pointcut publicCode(): call (public * *.*(..));
	
	/**
	 * TODO: remove
	 * All the public code except our security packages code
	 */
	public pointcut allButSecurityPackage() : publicCode() && !securityPackage();
	
	/**
	 * Selecteer de te beveiligen klasses of packages in deze
	 */
	public abstract pointcut selectAccessMethods();
	
	/**
	 * What do we want to secure? Basicly, select the single_accesspoint here, or create it
	 * by adding all the accesspoints to the code
	 */
	public abstract pointcut singleAccessPoint(SingleAccessPoint sap);
	
	/**
	 * Totaal systeem dat beveiligd wordt
	 * SingleAccessPoint(sap) && selectAccessMethods()
	 */
	public pointcut secureSystem(SingleAccessPoint sap): //!securityPackage()
		selectAccessMethods()
		&& singleAccessPoint(sap);
	
	Object around(SingleAccessPoint sap) : secureSystem(sap) {
		
		if (this.session_id == null) {
			this.session_id = checkpoint.getSessionId(null);
		}
		
		Object[] params = new Object[2];
		params[0] = thisJoinPoint.toShortString();
		params[1] = thisJoinPoint.getArgs();
		
		if (checkpoint.checkMe(params, sap, session_id)) {
			return proceed(sap);
		}
		
		sap.returnMessage("Operation not permited");
		return new Boolean(false);
	}

}
